package org.zfm.base.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.zfm.base.service.IVerifyCodeService;
import org.zfm.constants.BasicConstant;
import org.zfm.user.domain.dto.SmsCodeDto;
import org.zfm.user.mapper.UserMapper;
import org.zfm.util.utils.VerifyCodeUtils;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String getCodeImage(String key) {
        //生成一个四位数的随机字符串
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //将此字符串放入redis 并且设置过期时间
        redisTemplate.opsForValue().set(key,code,2,TimeUnit.MINUTES);
        //将此字符串合成图片并加密为base64数据字符串进行返回
        try {
            String base64 = VerifyCodeUtils.VerifyCode(100, 38, code);
            return base64;
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public void getSmsCode(SmsCodeDto dto) {
        // 1 判空
        if(StringUtils.isBlank(dto.getImageCode())||StringUtils.isBlank(dto.getImageCodeKey())||
                StringUtils.isBlank(dto.getPhone())){
            throw new RuntimeException("请先填写完整！！");
        }
        // 2 获取redis中的图形验证码 并且判断图形验证码是否正确
        String imageCode = (String)redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if(!dto.getImageCode().equalsIgnoreCase(imageCode)){
            throw new RuntimeException("验证码错误！请重新操作");
        }
        // 3 判断该手机号是否被注册过
        if(Objects.nonNull(userMapper.getByPhone(dto.getPhone()))){
            throw new RuntimeException("请勿重复注册！！！");
        }
        // 4 获取redis中的该手机号的验证码 判断验证码是否过期 如果没有过期，就用以前的 如果过期了就重新生成
        String smsCodeAndTime = (String) redisTemplate.opsForValue().get(BasicConstant.smsRegisterKeyPrefix + dto.getPhone());
        String smsCode = "";
        if(StringUtils.isBlank(smsCodeAndTime)){
            smsCode = VerifyCodeUtils.generateVerifyCode(6);
        }else {
            smsCode = smsCodeAndTime.split(":")[1];
            // 5 判断验证码是否过了重发时间
            Long originalSendTime = Long.parseLong(smsCodeAndTime.split(":")[0]);
            if((System.currentTimeMillis()-originalSendTime)<(1*60*1000)){
                throw new RuntimeException("请勿频繁操作！！！");
            }
        }
        // 6 重新设置验证码的发送时间和过期时间
        redisTemplate.opsForValue().set(BasicConstant.smsRegisterKeyPrefix +dto.getPhone(),
                System.currentTimeMillis()+":"+smsCode);
        // 7 发送短信
        // @Todo 发送短信
        System.out.println("发送短信验证码："+smsCode);
    }

    /**
     * 微信绑定电话时，获取手机验证码
     * @param phone
     */
    @Override
    public void getBindSmsCode(String phone) {
        //非空校验
        if(StringUtils.isBlank(phone)){
            throw new RuntimeException("参数错误，请填写完整后，重新操作！！！");
        }
        //获取redis中存储的短信，判断是否过了重发时间
        String timeAndSmsCode = (String) redisTemplate.opsForValue().get(BasicConstant.wx_bind_ + ":" + phone);
        if(StringUtils.isNotBlank(timeAndSmsCode)){
            long time = Long.parseLong(timeAndSmsCode.split(":")[0]);
            if((System.currentTimeMillis()-time) > 1*60*1000){
                throw new RuntimeException("请勿频繁操作");
            }
        }else {
            String smsCodeToBind = VerifyCodeUtils.generateVerifyCode(6);
            redisTemplate.opsForValue().set(BasicConstant.wx_bind_+":"+phone,System.currentTimeMillis()
                    +":"+smsCodeToBind,5,TimeUnit.MINUTES);
            // @Todo 发送短信验证码
            System.out.println(smsCodeToBind);
        }
    }

    @Override
    public void smsLoginCode(String phone) {
        //参数校验
        if (StringUtils.isBlank(phone)){{
            throw new RuntimeException("参数错误！！！");
        }}
        //随机生成验证码
        String smsLoginCode = VerifyCodeUtils.generateVerifyCode(6);
        //保存到redis
        redisTemplate.opsForValue().set(BasicConstant.smsLoginCode_prefix+phone,
                smsLoginCode,5,TimeUnit.MINUTES);
        //发送验证码
        System.out.println(smsLoginCode);
    }

    @Override
    public void getPasswordSmsCode(String phone) {
        //参数校验
        if (StringUtils.isBlank(phone)){{
            throw new RuntimeException("参数错误！！！");
        }}
        //随机生成验证码
        String rePasswordSmsCode = VerifyCodeUtils.generateVerifyCode(6);
        //保存到redis
        redisTemplate.opsForValue().set(BasicConstant.rePassword_sms_prefix+phone,
                rePasswordSmsCode,5,TimeUnit.MINUTES);
        //发送验证码
        System.out.println(rePasswordSmsCode);
    }

}
